在 JavaScript 中,原始型別有以下幾種:
true
, false
兩個值null
的值除了上述的六種原始型別,其餘都是物件型別 Object,包含很常使用的陣列、函式等。
而 Symbol
是 ES6
推出的資料型別,今天就來看個範例了解一下他的用法唄!
Symbol([description])
Symbol
的值都是獨一無二的,可以保證不會跟其他的屬性名產生衝突const bunny = Symbol();
const rabbit = Symbol();
bunny == rabbit; //false
bunny === rabbit; //false
( )
中加入對此 Symbol
的描述const bunny = Symbol('可愛的小兔子');
const rabbit = Symbol('野兔');
description
取得 Symbol
的描述內容const bunny = Symbol('可愛的小兔子');
bunny.description // "可愛的小兔子"
for 迴圈
、for..in
等方法遍歷,需要使用 Object.getOwnPropertySymbols()
方法Symbol
值放在中括號 []
,不然會被當字串.
取得屬性值,要使用中括號 [ ]
假如我們有個物件 classMate
,紀錄同學的資訊,一般會這樣寫:
const classMate = {
'宜蓁' : { score: 70, sleep: '3:00', drink: true },
'chita' : { score: 90, sleep: '20:00', drink:false },
'宜蓁' : { score: 100, sleep: '19:00', drink: false },
}
因為宜蓁這個菜市場名太容易撞名了,班上就剛好有兩位宜蓁同學,我們 console.log classMate
物件看看長怎樣:
哇咧~發現第二個宜蓁資料覆蓋掉第一個宜蓁了QQ~直接被忽略,好可憐,如果去改名又很麻煩,但別擔心,在這時候其實我們就可以使用 Symbol
來解決這個窘境,皆大歡喜:
const classMate = {
[Symbol('宜蓁')] : { score: 70, sleep: '3:00', drink: true },
[Symbol('chita')] : { score: 90, sleep: '20:00', drink:false },
[Symbol('宜蓁')] : { score: 100, sleep: '19:00', drink: false },
}
我們看看 console.log 有啥:
成功囉!Symbol
的值都是唯一的,所以兩位宜蓁的值並不會相等,也就不會有原本的覆蓋問題了,所以 Symbol
可以解決物件屬性中命名衝突的問題!另外在這裡要特別注意,定義屬性鍵名的時候一定要將 Symbol
值放在中括號 []
裡面,否則屬性的鍵名會當做字串而不是 Symbol
值哦!
如果我們要從物件 classMate
中取得屬性存到 myFriends
時,就需要這樣寫:
const classMate = {
[Symbol('宜蓁')] : { score: 70, sleep: '3:00', drink: true },
[Symbol('chita')] : { score: 90, sleep: '20:00', drink:false },
[Symbol('宜蓁')] : { score: 100, sleep: '19:00', drink: false },
}
const myFriends = Object.getOwnPropertySymbols(classMate).map(item => classMate[item]);
console.log(myFriends);
來 console.log
看一下:
成功取得囉!這邊要注意在取得 Symbol
屬性值的時候不能通過點運算子 .
去訪問,因為點運算子後面要是字串,不會讀取 Symbol 值作為識別符號所指代的值,所以這裡需要用中括號 []
取得屬性的值。
了解完了 Symbol
的用法,我們來看看 ESLint airbnb 的規則怎麼說:
1.1 Symbols cannot be faithfully polyfilled, so they should not be used when targeting browsers/environments that don’t support them natively.
恩~英文不太好,求大神翻譯囉!
我不是前端工程師,但看了這個Polyfill的單字覺得挺有意思的,就去查了一下:
Symbols cannot be faithfully polyfilled, so they should not be used when targeting browsers/environments that don’t support them natively.
白話一點的意思我想大概是:Symbol
這個功能不完全是一個Polyfill,因此在使用時需注意舊版瀏覽器/環境是否有支援。
Polyfill的解釋引用字這:
Polyfill的準確意思為:用於實現瀏覽器並不支援的原生API的程式碼。